package ee.logsimulator.parser;

import ee.logsimulator.data.Actor;
import ee.logsimulator.data.Amount;
import ee.logsimulator.data.Event;
import ee.logsimulator.data.Spell;
import ee.logsimulator.data.Type;
import ee.logsimulator.parser.data.CombatLog;
import ee.logsimulator.parser.data.FlaggedActor;
import ee.logsimulator.parser.data.Lines;
import ee.logsimulator.parser.data.ParseActor;
import ee.logsimulator.parser.data.ParseEvent;
import ee.logsimulator.parser.data.ParseResult;
import ee.logsimulator.parser.data.ParseSpell;
import ee.logsimulator.parser.data.Report;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;

import com.google.gson.Gson;

public class LogParser {
  private String initialUrl;

  public static void main(String[] args) {
    Calendar now = Calendar.getInstance();
    now.set(2012, 0, 1);
    Calendar past = Calendar.getInstance();
    past.set(2009, 6, 16);
    System.out.println(now.getTime());
    System.out.println(past.getTime());
    System.out.println((now.getTime().getTime() - past.getTime().getTime()) / 1000 / 60 / 60 / 24);
  }

  public LogParser(String url) throws HttpException, IOException {
    initialUrl = url;
  }

  public List<Event> getParesedLog() throws HttpException, IOException {
    List<Event> events = new ArrayList<Event>();
    int page = 0;
    String url = initialUrl;
    ParseResult parse = parse(url);
    while (parse.lines.lines.length > 0) {
      for (int lineId : parse.lines.lines) {
        int[] entry = getEntry(parse, lineId);
        ParseActor source = getActor(parse, entry[2]);
        ParseActor target = getActor(parse, entry[3]);
        ParseEvent event = getEvent(parse, entry[4]);
        ParseSpell spell = getSpell(parse, event.spell);
        if (source == null || target == null) {
          continue;
        }

        Event e = new Event();
        e.setTimestamp(new Date(parse.report.startTime + entry[1]));
        e.setSource(new Actor(parse.report.sid, "" + source.uid, source.name, source.clazz));
        e.setTarget(new Actor(parse.report.sid, "" + target.uid, target.name, target.clazz));
        e.setSpell(new Spell(spell == null ? "Melee" : spell.name));
        e.setAmount(new Amount(event.amount, event.overkill, event.overheal, event.blocked, event.absorbed, event.resisted,
            event.flags == 1));
        e.setType(Type.fromType(event.type));
        e.setSubType(event.subType);
        events.add(e);
      }
      page++;
      url = initialUrl += "&page=" + page;
      parse = parse(url);
    }
    return events;
  }

  private ParseSpell getSpell(ParseResult parse, int id) {
    for (ParseSpell s : parse.combatLog.spells) {
      if (s.id == id) {
        return s;
      }
    }
    return null;
  }

  private ParseEvent getEvent(ParseResult parse, int id) {
    for (ParseEvent e : parse.combatLog.events) {
      if (e.id == id) {
        return e;
      }
    }
    return null;
  }

  private ParseActor getActor(ParseResult parse, int id) {
    int uid = 0;
    for (FlaggedActor a : parse.combatLog.flaggedActors) {
      if (a.id == id) {
        uid = a.uid;
        break;
      }
    }
    for (ParseActor a : parse.combatLog.actors) {
      if (a.uid == uid) {
        return a;
      }
    }
    return null;
  }

  private int[] getEntry(ParseResult parse, int lineId) {
    for (int[] e : parse.combatLog.entries) {
      if (e[0] == lineId) {
        return e;
      }
    }
    return null;
  }

  private ParseResult parse(String url) throws HttpException, IOException {
    HttpClient client = new HttpClient();
    GetMethod get = new GetMethod(url);
    client.executeMethod(get);
    InputStream is = get.getResponseBodyAsStream();
    Gson gson = new Gson();
    BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
    StringBuilder html = new StringBuilder();
    String line = null;
    while ((line = reader.readLine()) != null) {
      html.append(line + "\n");
    }
    is.close();

    int indexOfSimpleQuery = html.indexOf("simpleQuery =");
    String simpleQueryJSON = html.substring(indexOfSimpleQuery + 13, html.indexOf("$(function()", indexOfSimpleQuery));
    simpleQueryJSON = simpleQueryJSON.substring(0, simpleQueryJSON.length() - 2);
    String reportJSON = html.substring(html.indexOf("report =") + 8, html.indexOf("combatLog ="));
    String combatLogJSON = html.substring(html.indexOf("combatLog =") + 12, html.indexOf("resultTimeRanges ="));

    ParseResult result = new ParseResult();
    result.combatLog = gson.fromJson(combatLogJSON, CombatLog.class);
    result.report = gson.fromJson(reportJSON, Report.class);
    result.lines = gson.fromJson(simpleQueryJSON, Lines.class);

    return result;
  }
}
